import { BeforeOpenModalResult } from '@farris/ide-property-panel';
import { DgControl } from '../../../../utils/dg-control';

/**
 * 响应式布局服务类
 */
export class ResponseLayoutEditorService {
    componentId: string;

    constructor(private domService: any, componentId: string) {
        this.componentId = componentId;
    }

    /** 布局配置参数 */
    responseLayoutConfig: FormResponseLayoutContext[];

    /** 控件 */
    originalControlMap = new Map<string, any>();

    /** 当前组件内的form节点 */
    formNode: any;

    /** 记录当前选中控件id */
    currentControlId: string;

    /** 记录当前选中控件所在的区域id */
    defaultGroupNumber: number;

    /**
     * 遍历控件所属Form下所有的控件，检测是否能弹出布局配置窗口，并收集配置参数
     * @param propertyData 控件属性值
     */
    checkCanOpenLayoutEditor(propertyData: any): BeforeOpenModalResult {

        const componentNode = this.domService.domDgMap.get(this.componentId);
        if (!componentNode || !componentNode.componentType || !componentNode.componentType.startsWith('form-col-')) {
            return { result: false, message: '只在卡片类组件中启用布局配置' };
        }

        this.formNode = this.domService.selectNode(componentNode, item => item.type === DgControl.Form.type);
        if (!this.formNode || !this.formNode.contents || this.formNode.contents.length === 0) {
            return { result: false, message: 'Form区域内没有控件，请先添加控件' };
        }
        this.currentControlId = propertyData.id;

        this.responseLayoutConfig = [];
        this.originalControlMap.clear();
        const firstGroup = this.formNode.contents[0].type === DgControl.FieldSet.type ? 0 : 1;
        this.getFormResonseLayoutConfig(this.formNode, this.responseLayoutConfig, firstGroup);


        const hasInvalidControl = this.responseLayoutConfig.find(config => !config.isSupportedClass);

        const responseParam: FormResponseLayoutParam = {
            defaultState: {
                defaultGroupNumber: this.defaultGroupNumber || 1,
                model: hasInvalidControl ? 'customize' : 'standard'
            },
            importData: this.responseLayoutConfig
        };

        return {
            result: true,
            parameters: responseParam
        };

    }

    checkIsInFormComponent() {
        const componentNode = this.domService.domDgMap.get(this.componentId);
        if (!componentNode || !componentNode.componentType || !componentNode.componentType.startsWith('form-col-')) {
            return false;
        }
        return true;
    }
    // tslint:disable-next-line:max-line-length
    getFormResonseLayoutConfig(propertyData: any, responseLayoutConfig: FormResponseLayoutContext[], group: number, isFieldSet = false) {
        // 前一个控件是否为分组控件，用于计算group值
        let isLastControlFieldSet = false;

        propertyData.contents.forEach(control => {
            if (control.type === DgControl.FieldSet.type) {

                group = group + 1;
                this.getFormResonseLayoutConfig(control, responseLayoutConfig, group, true);
                isLastControlFieldSet = true;
                return;
            }
            if (isLastControlFieldSet) {
                group = group + 1;
                isLastControlFieldSet = false;
            }
            const controlClass = control.appearance && control.appearance.class;
            const formResponseLayoutContext = new FormResponseLayoutContext();
            if (!controlClass) {
                formResponseLayoutContext.isSupportedClass = false;

            } else {
                this.resovleResponseContext(controlClass, formResponseLayoutContext);
            }
            formResponseLayoutContext.label = control.title || control.id;
            formResponseLayoutContext.id = control.id;
            formResponseLayoutContext.group = group;

            if (isFieldSet) {
                formResponseLayoutContext.fieldSetId = propertyData.id;
            }

            if (this.currentControlId === control.id) {
                this.defaultGroupNumber = group;
            }
            this.originalControlMap.set(control.id, control);
            responseLayoutConfig.push(formResponseLayoutContext);
        });
    }
    /**
     * 按照控件class样式，组装列编辑器需要的参数。
     * 标准的模板样式为col-12 col-md-6 col-xl-3 col-el-2
     * @param controlClass 控件class样式
     * @param formResponseLayoutContext 响应式布局参数实体
     */
    private resovleResponseContext(controlClass: string, formResponseLayoutContext: FormResponseLayoutContext) {

        const controlClassArray = controlClass.split(' ');
        const colClassItems = controlClassArray.filter(classItem => classItem.startsWith('col-'));

        // 没有写任何col-xx 的样式，不支持配置布局
        if (colClassItems.length === 0) {
            formResponseLayoutContext.isSupportedClass = false;
            return;
        }
        let colClass = colClassItems.find(item => /^col-([1-9]|10|11|12)$/.test(item));
        let colMDClass = colClassItems.find(item => /^col-md-([1-9]|10|11|12)$/.test(item));
        let colXLClass = colClassItems.find(item => /^col-xl-([1-9]|10|11|12)$/.test(item));
        let colELClass = colClassItems.find(item => /^col-el-([1-9]|10|11|12)$/.test(item));

        // 小屏幕：列数只支持1
        colClass = colClass || 'col-12';
        formResponseLayoutContext.columnInSM = parseInt(colClass.replace('col-', ''), 10);
        formResponseLayoutContext.displayWidthInSM = formResponseLayoutContext.columnInSM / 12;
        if (formResponseLayoutContext.displayWidthInSM !== 1) {
            formResponseLayoutContext.isSupportedClass = false;
        }

        // 中等屏幕，列数支持1,2
        colMDClass = colMDClass || 'col-md-' + formResponseLayoutContext.columnInSM;
        formResponseLayoutContext.columnInMD = parseInt(colMDClass.replace('col-md-', ''), 10);
        formResponseLayoutContext.displayWidthInMD = formResponseLayoutContext.columnInMD / 6;
        if (![1, 2].includes(formResponseLayoutContext.displayWidthInMD)) {
            formResponseLayoutContext.isSupportedClass = false;
        }

        // 大屏幕，列数支持1,2, 3, 4
        colXLClass = colXLClass || 'col-xl-' + formResponseLayoutContext.columnInMD;
        formResponseLayoutContext.columnInLG = parseInt(colXLClass.replace('col-xl-', ''), 10);
        formResponseLayoutContext.displayWidthInLG = formResponseLayoutContext.columnInLG / 3;
        if (![1, 2, 3, 4].includes(formResponseLayoutContext.displayWidthInLG)) {
            formResponseLayoutContext.isSupportedClass = false;
        }

        // 超大等屏幕，列数支持1,2, 3, 4, 5, 6
        colELClass = colELClass || 'col-el-' + formResponseLayoutContext.columnInLG;
        formResponseLayoutContext.columnInEL = parseInt(colELClass.replace('col-el-', ''), 10);
        formResponseLayoutContext.displayWidthInEL = formResponseLayoutContext.columnInEL / 2;
        if (![1, 2, 3, 4, 5, 6].includes(formResponseLayoutContext.displayWidthInEL)) {
            formResponseLayoutContext.isSupportedClass = false;
        }
    }

    /**
     * 按照列编辑器返回的配置修改控件class和顺序，并触发页面刷新
     * （针对带有分组的卡片，编辑器只支持控件在原分组下进行拖动，所以这里的处理相对简单，不涉及viewModel的修改）
     * @param componentId 控件所在组件ID
     */
    changeFormControlsByResponseLayoutConfig(componentId: string) {
        const componentNode = this.domService.domDgMap.get(componentId);
        const formNode = this.domService.selectNode(componentNode, item => item.type === DgControl.Form.type);

        const newFormContents = [];
        this.responseLayoutConfig.forEach(config => {
            // 原控件节点
            const controlNode = this.originalControlMap.get(config.id);
            const controlClass = controlNode.appearance && controlNode.appearance.class;

            if (controlClass) {
                const controlClassArray = controlClass.split(' ');
                const otherClassItems = controlClassArray.filter(classItem => !classItem.startsWith('col-'));

                const colClass = 'col-' + config.columnInSM;
                const colMDClass = 'col-md-' + config.columnInMD;
                const colXLClass = 'col-xl-' + config.columnInLG;
                const colELClass = 'col-el-' + config.columnInEL;

                const newClassItems = [colClass, colMDClass, colXLClass, colELClass].concat(otherClassItems);
                controlNode.appearance.class = newClassItems.join(' ');
            }

            if (config.fieldSetId) {
                // 分组节点
                const originFieldSetNode = formNode.contents.find(c => c.id === config.fieldSetId);
                const newFieldSetNode = newFormContents.find(c => c.id === config.fieldSetId);
                if (!newFieldSetNode) {
                    newFormContents.push(originFieldSetNode);
                    originFieldSetNode.contents = [controlNode];
                } else {
                    newFieldSetNode.contents.push(controlNode);
                }
            } else {
                // 未分组节点
                newFormContents.push(controlNode);
            }

        });

        formNode.contents = newFormContents;
        return formNode.id;

        // this.formServ.refreshFormDesigner.next();
    }
}



/**
 * 响应式布局参数实体。
 * 默认按照小屏sm、中等md、大屏lg、超大屏el 划分屏幕大小
 * ux约定：小屏上显示1列（每个控件占12栅格），中屏显示2列（每个控件占6栅格），大屏显示4列（每个控件占3栅格），超大屏显示6列（每个控件占2栅格），
 */
export class FormResponseLayoutContext {

    /** 控件标题 */
    public label: string;

    /** 控件id */
    public id: string;

    /** 每个控件占用的栅格数 */
    public columnInSM = 12;
    public columnInMD = 6;
    public columnInLG = 3;
    public columnInEL = 2;


    /** 每个控件占用的列数 */
    public displayWidthInSM = 1;
    public displayWidthInMD = 1;
    public displayWidthInLG = 1;
    public displayWidthInEL = 1;

    /** 编辑器内部默认显示的屏幕大小-----可以去掉 */
    public displayColumnCountAtBreakPoint = 'md';

    /** 控件所在行，传0即可-----编辑器内部使用 */
    public tagRow = 0;

    /** 控件是否显示上方空白：传0即可-----编辑器内部使用 */
    public showTopBorder = 0;

    /** 区域，从1开始。卡片内的控件从上往下，从左往右划分区域，遇到分组fieldSet时group+1，分组结束后group+1 */
    public group: number;

    /** 控件是否符合标准的class配置(设计器用的) */
    public isSupportedClass = true;

    /** 控件所在分组id(设计器用的) */
    public fieldSetId: string;

}

class FormResponseLayoutParam {
    defaultState: {
        /** 当前控件所在的区域 */
        defaultGroupNumber: number;

        /**  控件是否符合标准的class配置。只要当前卡片中有一个控件样式不符合标准，那么所有控件的model属性都是customize */
        model: 'standard' | 'customize';
    };
    importData: FormResponseLayoutContext[];
}
